package jfdi;

import java.util.ArrayList;
import java.util.List;

import util.Mlog;

import jfdi.event.TouchListener;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;

public class RootNode extends View {

    private Node mTree;
    private NodeActivity mActivity;
    private List<TouchListener> mTouchList;
    private Paint mPaint;
    private int[] mOffset;
    private int mOffsetX;
    private int mOffsetY;

    public RootNode(Context context) {
        super(context);
        mActivity = (NodeActivity) context;
        setWillNotDraw(false);
        mPaint = new Paint();
        mPaint.setColor(Color.MAGENTA);
        mOffset = new int[2];
    }

    public void setNode(Node t) {
        mTree = t;
    }

    @Override
    public boolean isOpaque() {
        return true;
    }
    
    public void addTouchListener(TouchListener tl) {
        if (mTouchList == null) {
            mTouchList = new ArrayList<TouchListener>();
        }
        mTouchList.add(tl);
    }
    
    public void removeTouchListener(TouchListener tl) {
        if (mTouchList != null) {
            mTouchList.remove(tl);
        }
    }

    @Override
    protected void onMeasure(int wspec, int hspec) {
        int w = MeasureSpec.getSize(wspec);
        int h = MeasureSpec.getSize(hspec);
        setMeasuredDimension(w, h);
    }

    @Override
    public void onLayout(boolean changed, int l, int t, int r, int b) {
        if (changed && ((r - l) > 0)) {
            getLocationOnScreen(mOffset);
            mTree.layout(l, t, r, b);
        }
    }

    @Override
    public void onDraw(Canvas canvas) {
        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawRect(0, 0, getWidth(), getHeight(), mPaint);
        mTree.draw(canvas);
    }

    long mLastTime = System.currentTimeMillis();
    @Override
    public boolean dispatchTouchEvent(MotionEvent evt) {
        if (evt.getActionMasked() == MotionEvent.ACTION_MOVE) {
            long now = System.currentTimeMillis();
//            Mlog.i("node", "delta time: ", now - mLastTime);
            if ((now - mLastTime) >= 16) {
                handleMotionEvent(evt);
                mLastTime = now;
            }
        } else {
            handleMotionEvent(evt);
        }
        return true;
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (KeyEvent.ACTION_UP == event.getAction() && event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
            mActivity.finish();
        }
        return true;
    }

    @Override
    public boolean dispatchKeyShortcutEvent(KeyEvent event) {
        return true;
    }


    @Override
    public boolean dispatchTrackballEvent(MotionEvent event) {
        return true;
    }

    @Override
    public boolean dispatchGenericMotionEvent(MotionEvent event) {
        return true;
    }

    private void handleMotionEvent(MotionEvent evt) {
        if (mTouchList != null) {
            final int n = mTouchList.size();
            evt.offsetLocation(-mOffset[0], -mOffset[1]);
            for (int i = 0; i < n; i++) {
                TouchListener tl = mTouchList.get(i);
                boolean down = evt.getActionMasked() == MotionEvent.ACTION_DOWN;
                if (down || tl.isActive()) {
                    tl.onTouchEvent(evt);
                }
            }
        }

    }
    
    private static final int MOTION = 101;
    private static final int INVAL = 102;
    
    private Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch(msg.what) {
            case INVAL:
                RootNode.super.invalidate();
                break;
            }
        }
    };
    
    public Handler getHandler() {
        return mHandler;
    }
    
    
}
